﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace ImageResizer
{
    public class ResizeImage
    {
        #region "Private Properties"
        #endregion

        #region "Public Properties"
        #endregion

        #region "Constructors"
        public ResizeImage()
        {
        }
        #endregion

        #region "Private Methods"
        #endregion

        #region "Public Methods"
        /// <summary>
        /// Saves an image to specified size and sets DPI to 72.
        /// </summary>
        /// <param name="ImagePath">Path to Image</param>
        /// <param name="TargetSize">Resize to</param>
        /// <param name="FileName">File name to save as</param>
        public static string SaveImageFile(string ImagePath, int TargetSize, string FileName)
        {
            using (Image Img = Image.FromFile(ImagePath))
            {
                using (MemoryStream MemStream = new MemoryStream())
                {
                    Img.Save(MemStream, ImageFormat.Jpeg);

                    return SaveImageFile(MemStream.ToArray(), TargetSize, FileName);
                }
            }

        }
        /// <summary>
        /// Saves an image to specified size and sets DPI to 72.
        /// </summary>
        /// <param name="Image">Byte Array of Image</param>
        /// <param name="TargetSize">Resize to</param>
        /// <param name="FileName">File name to save as</param>
        public static string SaveImageFile(byte[] Image, int TargetSize, string FileName)
        {
            string ret = "";

            try
            {
                using (System.Drawing.Image OldImage = System.Drawing.Image.FromStream(new MemoryStream(Image)))
                {
                    Size NewSize = CalculateDimensions(OldImage.Size, TargetSize);
                    using (Bitmap NewImage = new Bitmap(NewSize.Width, NewSize.Height))
                    {
                        using (Graphics Canvas = Graphics.FromImage(NewImage))
                        {
                            NewImage.SetResolution(72, 72);
                            Canvas.SmoothingMode = SmoothingMode.AntiAlias;
                            Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            Canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            Canvas.DrawImage(OldImage, new Rectangle(new Point(0, 0), NewSize));
                            using (MemoryStream MemStream = new MemoryStream())
                            {
                                NewImage.Save(MemStream, ImageFormat.Jpeg);
                                ret = WriteToFile(FileName, MemStream.GetBuffer());
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //remove image if needed (may  not need)
                DeleteImageFile(FileName);

                ret = ex.Message;
            }

            return ret;
        }

        /// <summary>
        /// Will calculate the new Width and Height based on original size and what you want to resize to.
        /// </summary>
        /// <param name="OldSize">Original Size</param>
        /// <param name="TargetSize">New Size</param>
        /// <returns>new Size</returns>
        public static Size CalculateDimensions(Size OldSize, int TargetSize)
        {
            Size NewSize = new Size();
            if (OldSize.Width > TargetSize || OldSize.Height > TargetSize)
            {
                if (OldSize.Height > OldSize.Width)
                {
                    NewSize.Width = (int)(OldSize.Width * ((float)TargetSize / (float)OldSize.Height));
                    NewSize.Height = Convert.ToInt32(TargetSize);
                }
                else
                {
                    NewSize.Width = Convert.ToInt32(TargetSize);
                    NewSize.Height = (int)(OldSize.Height * ((float)TargetSize / (float)OldSize.Width));
                }
            }
            else
            {
                NewSize.Width = OldSize.Width;
                NewSize.Height = OldSize.Height;
            }
            return NewSize;
        }

        /// <summary>
        /// Returns a byte array of the newly resized image
        /// </summary>
        /// <param name="path">path to image</param>
        /// <param name="size">target size</param>
        /// <returns>byte array of resized image</returns>
        public static byte[] GetResizedImage(String path, Size size)
        {
            using (Bitmap imgIn = new Bitmap(path))
            {
                if (imgIn.Width > size.Width || imgIn.Height > size.Height)
                {
                    double y = imgIn.Height;
                    double x = imgIn.Width;
                    double factor = 1;

                    if (size.Width > 0)
                    {
                        factor = size.Width / x;
                    }
                    else if (size.Height > 0)
                    {
                        factor = size.Height / y;
                    }

                    using (System.IO.MemoryStream outStream = new System.IO.MemoryStream())
                    {
                        using (Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor)))
                        {
                            using (Graphics g = Graphics.FromImage(imgOut))
                            {
                                g.Clear(Color.White);
                                g.SmoothingMode = SmoothingMode.AntiAlias;
                                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                                g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)), new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);
                                imgOut.Save(outStream, GetImageFormat(path));
                                return outStream.ToArray();
                            }
                        }
                    }
                }
                else
                {
                    using (MemoryStream outStream = new MemoryStream())
                    {
                        imgIn.Save(outStream, GetImageFormat(path));

                        return outStream.ToArray();
                    }
                }
            }
        }

        /// <summary>
        /// Returns the format type
        /// </summary>
        /// <param name="path"></param>
        /// <returns>image format</returns>
        public static ImageFormat GetImageFormat(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return ImageFormat.Bmp;
                case ".gif": return ImageFormat.Gif;
                case ".jpg": return ImageFormat.Jpeg;
                case ".png": return ImageFormat.Png;
                default: break;
            }
            return ImageFormat.Jpeg;
        }

        /// <summary>
        /// Write Image to disk.
        /// </summary>
        /// <param name="FileName">File name to save as</param>
        /// <param name="Bytes">Byte Array to write</param>
        private static string WriteToFile(string FileName, byte[] Bytes)
        {
            string ret = "";
            try
            {
                if (FileName != "")
                {
                    FileStream ImageStream = File.Open(FileName, FileMode.CreateNew, FileAccess.ReadWrite);
                    {
                        try
                        {
                            ImageStream.Write(Bytes, 0, Bytes.Length);
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                        finally
                        {
                            ImageStream.Flush();
                            ImageStream.Close();
                            ImageStream.Dispose();
                            //over kill??
                            ImageStream = null;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ret = ex.Message;
            }

            return ret;
        }

        /// <summary>
        /// Deletes an image file form disk.
        /// </summary>
        /// <param name="FileName">File name to delete</param>
        public static string DeleteImageFile(string FileName)
        {
            string ret = "";
            try
            {
                if (FileName != "")
                {
                    if (File.Exists(FileName))
                    {
                        File.Delete(FileName);
                    }
                }
            }
            catch (Exception ex)
            {
                ret = ex.Message;
            }

            return ret;
        }

        #endregion
    }
}

//test svn update